作者:yf_992258 | 来源:互联网 | 2023-02-13 14:24
最近我学习使用node和node-sqlite3来操作sqlite3,这里有一个示例.
var sqlite3 = require('sqlite3');
var db = new sqlite3.Database(':memory:');
db.serialize(function() {
db.run("CREATE TABLE test(info TEXT)");
db.run("INSERT INTO test (info) VALUES ('info1')");
})
db.close();
文档说db.serialized
用来确保SQL行按顺序执行,但我很困惑,为什么不按顺序执行它们db.serialize
,毕竟它们会从事件队列中拉出并按顺序执行?它在这里如何运作?
如果只有一个sql要执行,运行它是否安全,db.serialize
如下所示?
var sqlite3 = require('sqlite3');
var db = new sqlite3.Database(':memory:');
db.run("CREATE TABLE test(info TEXT)");
db.close();
Malvineous..
26
serialize()
函数内的每个命令都保证在下一个命令启动之前完成执行.
在您的示例中,CREATE TABLE
将在INSERT
运行之前完成.如果你没有使用serialize()
那么CREATE TABLE
和INSERT
语句将并行运行.它们会一个接一个地快速启动,INSERT
实际上可能在创建表之前完成,从而在尝试将数据插入到不存在的表中时出错.
这被称为竞争条件,因为每次运行程序时,您都可能获得不同的胜利者.如果CREATE TABLE
赢得比赛,那么该计划将正常运作.但如果INSERT
赢得比赛,该计划将打破错误.既然你无法控制谁赢得比赛,那么即使从开始到结束serialize()
也会停止,确保你每次都获得相同的结果.INSERT
CREATE TABLE
在第二个只有一个语句的例子中,serialize()
仍然需要.这是因为run()
启动SQL查询但立即返回,使查询在后台运行.由于您的下一个命令是close()
数据库的一个命令,因此您将在查询仍在运行时将其截断.
由于serialize()
直到最后一个内部查询完成才返回,因此使用它将close()
一直保持到查询完成为止.
如果您使用的是不同类型的查询(例如,响应用户单击网页上的按钮,数据库在调用之间保持打开状态),那么您可能不需要serialize()
.它取决于每个查询后面的代码是否要求在它完成之前的查询.
在决定是否使用时serialize()
,将任何非序列化查询视为已注释掉,然后查看代码是否仍然有效可能会有所帮助.在上面的第一个例子中,删除CREATE TABLE
命令会破坏以下INSERT
语句(因为那时没有要插入的表),因此需要序列化这些语句.但是,如果您有两个CREATE TABLE
命令,那么删除一个命令不会影响另一个命令,因此这两个命令不必序列化.
(这个提示不适用于close()
- 经验法则只有close()
在一切都运行完毕后才会调用.)
1> Malvineous..:
serialize()
函数内的每个命令都保证在下一个命令启动之前完成执行.
在您的示例中,CREATE TABLE
将在INSERT
运行之前完成.如果你没有使用serialize()
那么CREATE TABLE
和INSERT
语句将并行运行.它们会一个接一个地快速启动,INSERT
实际上可能在创建表之前完成,从而在尝试将数据插入到不存在的表中时出错.
这被称为竞争条件,因为每次运行程序时,您都可能获得不同的胜利者.如果CREATE TABLE
赢得比赛,那么该计划将正常运作.但如果INSERT
赢得比赛,该计划将打破错误.既然你无法控制谁赢得比赛,那么即使从开始到结束serialize()
也会停止,确保你每次都获得相同的结果.INSERT
CREATE TABLE
在第二个只有一个语句的例子中,serialize()
仍然需要.这是因为run()
启动SQL查询但立即返回,使查询在后台运行.由于您的下一个命令是close()
数据库的一个命令,因此您将在查询仍在运行时将其截断.
由于serialize()
直到最后一个内部查询完成才返回,因此使用它将close()
一直保持到查询完成为止.
如果您使用的是不同类型的查询(例如,响应用户单击网页上的按钮,数据库在调用之间保持打开状态),那么您可能不需要serialize()
.它取决于每个查询后面的代码是否要求在它完成之前的查询.
在决定是否使用时serialize()
,将任何非序列化查询视为已注释掉,然后查看代码是否仍然有效可能会有所帮助.在上面的第一个例子中,删除CREATE TABLE
命令会破坏以下INSERT
语句(因为那时没有要插入的表),因此需要序列化这些语句.但是,如果您有两个CREATE TABLE
命令,那么删除一个命令不会影响另一个命令,因此这两个命令不必序列化.
(这个提示不适用于close()
- 经验法则只有close()
在一切都运行完毕后才会调用.)